
package vip.xiaonuo.biz.modular.lancerGoodskill.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.auth.core.pojo.SaBaseLoginUser;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.biz.core.utils.RedisUtil;
import vip.xiaonuo.biz.modular.lancerBrand.service.BizBrandService;
import vip.xiaonuo.biz.modular.lancerGoodsBox.service.BizGoodsBoxService;
import vip.xiaonuo.biz.modular.lancerUserGoods.entity.BizUserGoods;
import vip.xiaonuo.biz.modular.pojo.domain.BizBrand;
import vip.xiaonuo.biz.modular.pojo.domain.BizGoods;
import vip.xiaonuo.biz.modular.pojo.domain.BizGoodsBox;
import vip.xiaonuo.biz.modular.pojo.vo.ClientGoodsKillVO;
import vip.xiaonuo.common.consts.CacheConstant;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.biz.modular.lancerGoodskill.entity.BizGoodsKill;
import vip.xiaonuo.biz.modular.lancerGoodskill.mapper.BizGoodsKillMapper;
import vip.xiaonuo.biz.modular.lancerGoodskill.param.BizGoodsKillAddParam;
import vip.xiaonuo.biz.modular.lancerGoodskill.param.BizGoodsKillEditParam;
import vip.xiaonuo.biz.modular.lancerGoodskill.param.BizGoodsKillIdParam;
import vip.xiaonuo.biz.modular.lancerGoodskill.param.BizGoodsKillPageParam;
import vip.xiaonuo.biz.modular.lancerGoodskill.service.BizGoodsKillService;
import vip.xiaonuo.common.pojo.DbEnum;

import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 秒杀Service接口实现类
 *
 * @author Lancer
 * @date 2024/03/03 17:01
 **/
@Service
public class BizGoodsKillServiceImpl extends ServiceImpl<BizGoodsKillMapper, BizGoodsKill> implements BizGoodsKillService {


    @Override
    public void add(BizGoodsKillAddParam bizGoodsKillAddParam) {
        throw new CommonException("管理员暂时不支持添加秒杀！等待后期升级中");
    }

    @Autowired
    BizBrandService brandService;
    @Autowired
    BizGoodsBoxService bizGoodsBoxService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addBus(BizGoodsKillAddParam bizGoodsKillAddParam) {
        BizBrand byUserId = brandService.getBrandByUserId();
        // 获取商品盒子名称
        BizGoodsBox byId = bizGoodsBoxService.getObjById(bizGoodsKillAddParam.getGoodsBoxId());
        BizGoodsKill bizGoodsKill = BeanUtil.toBean(bizGoodsKillAddParam, BizGoodsKill.class);
        bizGoodsKill.setBrandId(byUserId.getId())
                .setBrandName(byUserId.getBrandName())
                .setGoodsBoxName(byId.getGoodsBoxName())
                .setGoodsBoxId(byId.getId());
        this.save(bizGoodsKill);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(BizGoodsKillEditParam bizGoodsKillEditParam) {
        editBus(bizGoodsKillEditParam);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void editBus(BizGoodsKillEditParam param) {
        // 获取商品盒子名称
        BizGoodsBox byId = bizGoodsBoxService.getObjById(param.getGoodsBoxId());

        BizGoodsKill bizGoodsKill = this.queryEntity(param.getId());
        BeanUtil.copyProperties(param, bizGoodsKill);

        bizGoodsKill.setGoodsBoxName(byId.getGoodsBoxName())
                .setGoodsBoxId(byId.getId());
        this.updateById(bizGoodsKill);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<BizGoodsKillIdParam> bizGoodsKillIdParamList) {
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(bizGoodsKillIdParamList, BizGoodsKillIdParam::getId));
    }

    @Override
    public BizGoodsKill detail(BizGoodsKillIdParam bizGoodsKillIdParam) {
        return this.queryEntity(bizGoodsKillIdParam.getId());
    }

    @Override
    public BizGoodsKill queryEntity(String id) {
        BizGoodsKill bizGoodsKill = this.getById(id);
        if (ObjectUtil.isEmpty(bizGoodsKill)) {
            throw new CommonException("秒杀不存在，id值为：{}", id);
        }
        return bizGoodsKill;
    }

    @Override
    public Page<BizGoodsKill> page(BizGoodsKillPageParam bizGoodsKillPageParam) {
        QueryWrapper<BizGoodsKill> queryWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotEmpty(bizGoodsKillPageParam.getGoodsBoxId())) {
            queryWrapper.lambda().like(BizGoodsKill::getGoodsBoxId, bizGoodsKillPageParam.getGoodsBoxId());
        }
        if (ObjectUtil.isNotEmpty(bizGoodsKillPageParam.getBrandName())) {
            queryWrapper.lambda().like(BizGoodsKill::getBrandName, bizGoodsKillPageParam.getBrandName());
        }
        if (ObjectUtil.isNotEmpty(bizGoodsKillPageParam.getStartKillStartTime()) && ObjectUtil.isNotEmpty(bizGoodsKillPageParam.getEndKillStartTime())) {
            queryWrapper.lambda().between(BizGoodsKill::getKillStartTime, bizGoodsKillPageParam.getStartKillStartTime(), bizGoodsKillPageParam.getEndKillStartTime());
        }
        if (ObjectUtil.isNotEmpty(bizGoodsKillPageParam.getStartKillEndTime()) && ObjectUtil.isNotEmpty(bizGoodsKillPageParam.getEndKillEndTime())) {
            queryWrapper.lambda().between(BizGoodsKill::getKillEndTime, bizGoodsKillPageParam.getStartKillEndTime(), bizGoodsKillPageParam.getEndKillEndTime());
        }
        if (ObjectUtil.isAllNotEmpty(bizGoodsKillPageParam.getSortField(), bizGoodsKillPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(bizGoodsKillPageParam.getSortOrder());
            queryWrapper.orderBy(true, bizGoodsKillPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(bizGoodsKillPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByAsc(BizGoodsKill::getId);
        }
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Override
    public List<BizGoodsKill> getAllSkillInfo(){
        LambdaQueryWrapper<BizGoodsKill> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.ge(BizGoodsKill::getKillEndTime,DateUtil.now());
        return this.list(queryWrapper);
    }
    @Override
    public Page<BizGoodsKill> pageBus(BizGoodsKillPageParam bizGoodsKillPageParam) {
        QueryWrapper<BizGoodsKill> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(BizGoodsKill::getBrandId, StpLoginUserUtil.getLoginUser().getId());
        if (ObjectUtil.isNotEmpty(bizGoodsKillPageParam.getGoodsBoxId())) {
            queryWrapper.lambda().like(BizGoodsKill::getGoodsBoxId, bizGoodsKillPageParam.getGoodsBoxId());
        }
        if (ObjectUtil.isNotEmpty(bizGoodsKillPageParam.getBrandName())) {
            queryWrapper.lambda().like(BizGoodsKill::getBrandName, bizGoodsKillPageParam.getBrandName());
        }
        if (ObjectUtil.isNotEmpty(bizGoodsKillPageParam.getStartKillStartTime()) && ObjectUtil.isNotEmpty(bizGoodsKillPageParam.getEndKillStartTime())) {
            queryWrapper.lambda().between(BizGoodsKill::getKillStartTime, bizGoodsKillPageParam.getStartKillStartTime(), bizGoodsKillPageParam.getEndKillStartTime());
        }
        if (ObjectUtil.isNotEmpty(bizGoodsKillPageParam.getStartKillEndTime()) && ObjectUtil.isNotEmpty(bizGoodsKillPageParam.getEndKillEndTime())) {
            queryWrapper.lambda().between(BizGoodsKill::getKillEndTime, bizGoodsKillPageParam.getStartKillEndTime(), bizGoodsKillPageParam.getEndKillEndTime());
        }
        if (ObjectUtil.isAllNotEmpty(bizGoodsKillPageParam.getSortField(), bizGoodsKillPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(bizGoodsKillPageParam.getSortOrder());
            queryWrapper.orderBy(true, bizGoodsKillPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(bizGoodsKillPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByAsc(BizGoodsKill::getId);
        }
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Autowired
    RedisUtil redisUtil;
    @Override
    public void killGoods(String skillId, HttpServletResponse httpResponse) {
        // 1 redis 获取
        Object hget = redisUtil.hget(CacheConstant.SKILL_GOODS_CACHE_KEY, skillId);
        if (ObjectUtil.isEmpty(hget)){
            throw new CommonException("秒杀已结束!");
        }
        // 2 库存减一
        Integer originCurrStock=(Integer)hget;
        if (originCurrStock-1<1){
            throw new CommonException("已售空！");
        }
        redisUtil.hset(CacheConstant.SKILL_GOODS_CACHE_KEY,skillId,originCurrStock-1);
        // 3 秒杀成功，开始生成订单


    }
//    public String buyGoods(String skillId, Integer count) {
//        // 查询源商品id
//        BizGoodsKill kill = this.getById(skillId);
//        kill.get
//        BizUserGoods bizUserGoods = new BizUserGoods();
//        SaBaseLoginUser loginUser = StpLoginUserUtil.getLoginUser();
//        BizGoodsBox box = bizGoodsBoxService.getObjByGoodsId(id);
//        // 商品
//        BizGoods bizGoods = goodsService.getById(id);
//        bizUserGoods
//                .setCount(count)
//                .setStatus(DbEnum.ORDER_STATUS.NO_PAY.getValue())
//                .setGoodsId(bizGoods.getId())
//                .setGoodsName(bizGoods.getGoodsName());
//        // 商品盒子
//        bizUserGoods.setGoodsBoxId(box.getId())
//                .setGoodsBoxName(box.getGoodsBoxName());
//        // 品牌信息
//        bizUserGoods.setBrandId(box.getBrandId())
//                .setBrandName(box.getBrandName());
//        // 消费者信息
//        bizUserGoods.setCreateUser(loginUser.getId())
//                .setUserName(loginUser.getName());
//        String categoryId = box.getCategoryId();
//        // 类型
//        bizUserGoods.setCategoryId(categoryId);
//        // 金钱计算
//        Integer payMoney = getPayMoney(bizGoods, count, loginUser.getId());
//        bizUserGoods.setPayMoney(payMoney);
//        userGoodsService.save(bizUserGoods);
//        // 直接返回生成的订单id
//        return bizUserGoods.getId();
//    }

    @Override
    public Page<ClientGoodsKillVO> pageClient(BizGoodsKillPageParam bizGoodsKillPageParam) {
        Page<ClientGoodsKillVO> voPage = new Page<>();
        QueryWrapper<BizGoodsKill> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lt("kill_start_time", DateUtil.now())
                .ge("kill_end_time",DateUtil.now())
                .orderByAsc("kill_end_time");
        Page<BizGoodsKill> page = this.page(CommonPageRequest.defaultPage(), queryWrapper);
        List<BizGoodsKill> records = page.getRecords();
        List<ClientGoodsKillVO> collect = records.stream().map(x -> {
            ClientGoodsKillVO vo = new ClientGoodsKillVO();

            // 查询商品盒子信息
            BizGoodsBox byId = bizGoodsBoxService.getObjById(x.getGoodsBoxId());
            BeanUtil.copyProperties(byId, vo);
            BeanUtil.copyProperties(x, vo);
            // 设置秒杀id
            vo.setId(x.getId());
            // 计算秒杀进度
            double currStock = x.getOriginCurrStock();
            double killStock = x.getOriginKillStock();
            Integer speed = (int) (((killStock-currStock) / killStock) * 100);
            vo.setKillSpeed(speed);
            return vo;
        }).collect(Collectors.toList());
        voPage.setTotal(page.getTotal());
        voPage.setRecords(collect);
        return voPage;
    }

    @Override
    public Page<ClientGoodsKillVO> doingKill() {
        Page<ClientGoodsKillVO> voPage = pageClient(null);
        if (voPage.getTotal()>3){
            voPage.setTotal(3);
            voPage.setRecords(voPage.getRecords().subList(0,3));

        }
        List<ClientGoodsKillVO> records = voPage.getRecords();
        for (ClientGoodsKillVO vo : records) {
            // 设置倒计时
            Date killEndTime = vo.getKillEndTime();
            long time = new Date().getTime();
            long endTimeNumber = killEndTime.getTime() - time;
            vo.setEndTimeNumber(String.valueOf(endTimeNumber));
        }
        return voPage;
    }

    @Override
    public boolean isDoingKill(String id) {
        LambdaQueryWrapper<BizGoodsKill> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(BizGoodsKill::getGoodsBoxId,id)
                .le(BizGoodsKill::getKillStartTime,DateUtil.now())
                .ge(BizGoodsKill::getKillEndTime,DateUtil.now());
        return this.count(queryWrapper)>0;
    }
    @Override
    public void redGoodsNumberByBoxId(String boxId) {
        this.getBaseMapper().redGoodsNumberByBoxId(boxId);
    }
    @Override
    public void incGoodsNumberByBoxId(String id) {
        this.getBaseMapper().incGoodsNumberByBoxId(id);
    }


}
